package com.example.bhservice.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
//import com.aspose.words.Document;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.data.style.ParagraphStyle;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
//import jakarta.servlet.ServletOutputStream;
//import jakarta.servlet.http.HttpServletResponse;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.docx4j.Docx4J;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.springframework.web.bind.annotation.*;
//import com.aspose.cells.License;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;


@RestController
@CrossOrigin  //在controller类上添加此注解
public class testController {
    private final Object lock = new Object();

    @GetMapping("/test")
    public String setName() {
        return "水文分析";
    }


    @PostMapping("/ybd")
    public int ybd(@RequestBody String formData, HttpServletResponse response) throws
            Throwable {
        synchronized (lock) {


            // 本地开发测试环境
            String basePath = "D:/YH-2025/01-温州三澳/sa-go-gitee-sanao-wcy/public/";
            // 服务器生产环境
//            String basePath = "G:\\qdyh\\zdbz\\wzGo\\public\\";


            JSONObject form = JSONObject.parseObject(formData);
            class T1 {
                String k1;
            }
            class T2 extends T1 {
                String k2;
            }
            class T3 extends T2 {
                String k3;
            }

            class T4 extends T3 {
                String k4;
            }

            class T5 extends T4 {
                String k5;
            }

            class T6 extends T5 {
                String k6;
            }

            class T7 extends T6 {
                String k7;
            }

            class T8 extends T7 {
                String k8;
            }
            class T9 extends T8 {
                String k9;
            }

            class T10 extends T9 {
                String k10;
            }

            class T11 extends T10 {
                String k11;
            }

            class T12 extends T11 {
                String k12;
            }

            class T13 extends T12 {
                String k13;
            }

            class T14 extends T13 {
                String k14;
            }

            class T15 extends T14 {
                String k15;
            }
            class T extends T15 {
                String k16;
            }

//        定义一个string变量
            String timeDay = "";
            String date1 = "";
            String type_sa = "";

            for (Map.Entry<String, Object> entry : form.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals("time")) {
                    timeDay = (String) value;
                }
                if (key.equals("date1")) {
                    date1 = (String) value;
                }
                if (key.equals("type")) {
                    type_sa = (String) value;
                }
            }
            String[] tableArr = new String[]{"df1", "df2", "df3", "hy1", "hy2", "hy3", "hx1", "hx2", "hx3", "zb1", "sa1", "sa2", "sa3", "sz1", "sz2", "yy1", "rahx1", "rayg1", "rayg2", "wzhx1", "wzhy1", "wzhy2", "hdrc1", "hsyc1", "dt1", "dt2", "dtzb1", "dtzb2", "xhl1", "xhl2"};
            LoopRowTableRenderPolicy loopRowTableRenderPolicy = new LoopRowTableRenderPolicy();
            ConfigureBuilder configureBuilder = Configure.newBuilder();
            for (int i = 0; i < tableArr.length; i++) {
                configureBuilder.bind(tableArr[i], loopRowTableRenderPolicy);
            }
            Configure config = configureBuilder.build();
            String finalSubTime = timeDay;
            String fileName = basePath + "预报单模板\\" + form.getString("type") + ".docx";
            String outName = "";
//        将时间通过-分割
            String[] timeArr = finalSubTime.split("-");
            outName = form.getString("fileName");
            outName = outName + ".docx";

            String docxPath = basePath + "ybd\\" + outName;
            String pdfPath = basePath + "ybd\\" + outName.split("\\.")[0] + ".pdf";
            String finalDate = date1;
            XWPFTemplate.compile(fileName, config).render(new HashMap<String, Object>() {{
                String[] imgeArr = new String[]{"img1", "img2", "img3", "img4", "img5"};
                //                String[] strArr = new String[]{"subTime", "es", "content1", "content2", "content3", "content4", "date1", "date2", "date3", "date4", "date5", "date6", "date7", "bh", "content5", "content6", "content7", "isContent5", "isContent6", "isContent7", "c"};
                //                String[] tableArr = new String[]{"df1", "df2", "df3", "hy1", "hy2", "hy3", "hx1", "hx2", "hx3", "zb1", "sa1", "sa2", "sa3", "sz1", "sz2", "yy1", "rahx1", "rayg1", "rayg2", "wzhx1", "wzhy1", "wzhy2", "hdrc1", "hsyc1", "dt1", "dt2", "dtzb1", "dtzb2", "xhl1", "xhl2"};


                String[] strArr = new String[]{"subTime", "es", "content1", "content2", "content3", "content4", "date1", "date2", "date3", "date4", "date5", "date6", "date7", "bh", "content5", "content6", "content7", "isContent5", "isContent6", "isContent7", "c"};
                String[] tableArr = new String[]{"df1", "df2", "df3", "hy1", "hy2", "hy3", "hx1", "hx2", "hx3", "zb1", "sa1", "sa2", "sa3", "sz1", "sz2", "yy1", "rahx1", "rayg1", "rayg2", "wzhx1", "wzhy1", "wzhy2", "hdrc1", "hsyc1", "dt1", "dt2", "dtzb1", "dtzb2", "xhl1", "xhl2"};
                for (int i = 0; i < imgeArr.length; i++) {
                    if (form.getJSONArray("imgs") != null) {
                        for (int j = 0; j < form.getJSONArray("imgs").size(); j++) {
                            put(imgeArr[j], Pictures.of(basePath + "\\png\\" + form.getJSONArray("imgs").getString(j)).fitSize().center().create());
                        }
                    }
                }
                for (int i = 0; i < strArr.length; i++) {
                    if (form.getString(strArr[i]) != null) {
                        put(strArr[i], form.getString(strArr[i]));
                    }
                }
                if (form.getJSONArray("pyja1") != null) {
                    JSONArray tableData = form.getJSONArray("pyja1");
                    for (int i = 0; i < tableData.size(); i++) {
                        JSONArray row = tableData.getJSONArray(i);
                        for (int j = 0; j < row.size(); j++) {
                            put("a" + i + j, row.getString(j));
                        }
                    }
                }
                if (form.getJSONArray("pyja2") != null) {
                    JSONArray tableData = form.getJSONArray("pyja2");
                    for (int i = 0; i < tableData.size(); i++) {
                        JSONArray row = tableData.getJSONArray(i);
                        for (int j = 0; j < row.size(); j++) {
                            put("b" + i + j, row.getString(j));
                        }
                    }
                }
//            针对nj的
                if (form.getJSONArray("nj1") != null) {
                    JSONArray tableData = form.getJSONArray("nj1");
                    List<T> list = new ArrayList<>();
//                Map<String, JSONArray> mergeMap = new HashMap<>();
                    put("nj1", new ArrayList<HashMap<String, Object>>() {{
                        for (int j = 0; j < tableData.size(); j++) {
                            int finalJ = j;
                            add(new HashMap<String, Object>() {
                                {
                                    JSONArray rowData = form.getJSONArray("nj1").getJSONArray(finalJ);
                                    T t = new T();
                                    for (int k = 0; k < rowData.size(); k++) {
                                        String key = "k" + (k + 1);
                                        String value = rowData.getString(k);
                                        put(key, value);
                                    }
                                }
                            });
                        }
                    }});
                }
                for (int i = 0; i < tableArr.length; i++) {
                    if (form.getJSONArray(tableArr[i]) != null) {
                        JSONArray item = form.getJSONArray(tableArr[i]);
                        String[][] twoDArray = item.toJavaObject(String[][].class);

                        Map<String, String>[] oneDArray = new HashMap[twoDArray.length];
                        for (int k = 0; k < twoDArray.length; k++) {
                            String[] row = twoDArray[k];
                            Map<String, String> map = new HashMap<>();
                            for (int j = 0; j < row.length; j++) {
                                String key = "k" + (j + 1);
                                String value = row[j];
                                map.put(key, value);
                            }
                            oneDArray[k] = map;
                        }

                        List<T> list = new ArrayList<>();
                        for (int k = 0; k < oneDArray.length; k++) {
                            T t = new T();
                            for (Map.Entry<String, String> entry : oneDArray[k].entrySet()) {
                                String key = entry.getKey();
                                String value = entry.getValue();
                                if (key.equals("k1")) {
                                    t.k1 = value;
                                }
                                if (key.equals("k2")) {
                                    t.k2 = value;
                                }
                                if (key.equals("k3")) {
                                    t.k3 = value;
                                }
                                if (key.equals("k4")) {
                                    t.k4 = value;
                                }
                                if (key.equals("k5")) {
                                    t.k5 = value;
                                }
                                if (key.equals("k6")) {
                                    t.k6 = value;
                                }
                                if (key.equals("k7")) {
                                    t.k7 = value;
                                }
                                if (key.equals("k8")) {
                                    t.k8 = value;
                                }
                                if (key.equals("k9")) {
                                    t.k9 = value;
                                }
                                if (key.equals("k10")) {
                                    t.k10 = value;
                                }
                                if (key.equals("k11")) {
                                    t.k11 = value;
                                }
                                if (key.equals("k12")) {
                                    t.k12 = value;
                                }
                                if (key.equals("k13")) {
                                    t.k13 = value;
                                }
                                if (key.equals("k14")) {
                                    t.k14 = value;
                                }
                                if (key.equals("k15")) {
                                    t.k15 = value;
                                }
                            }
                            list.add(t);
                        }
                        put(tableArr[i], list);

                    }
                }
            }}).writeToFile(docxPath);


            if (finalDate != "" && fileName.contains("sa.docx")) {
                XWPFDocument xwpfDocument = new XWPFDocument(Files.newInputStream(Paths.get(docxPath)));
                List<XWPFTable> tables = xwpfDocument.getTables();
                XWPFTable table = tables.get(2);
                //                合并第二行第一列到第四行第一列
                table.getRow(2).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
                table.getRow(3).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                table.getRow(4).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                table.getRow(5).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
                table.getRow(6).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                table.getRow(7).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                table.getRow(8).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
                table.getRow(9).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);

// type_sa 三澳日预报
                String sastr = "sa";
                if (type_sa.equals(sastr)) {
                    XWPFTable table1 = tables.get(0);
// table1.getRow(0).getCell(1).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
// table1.getRow(0).getCell(2).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
// table1.getRow(0).getCell(3).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
// table1.getRow(0).getCell(4).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                    // 设置第 2 行（索引 1）第一列单元格为垂直合并起点
                    table1.getRow(1).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);

// 设置第 3 行（索引 2）第一列单元格为继续合并
                    table1.getRow(2).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                    table1.getRow(3).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);


                    table1.getRow(4).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                }

                FileOutputStream out = new FileOutputStream(docxPath);
                xwpfDocument.write(out);
                out.close();
            }


            if (finalDate != null && !finalDate.isEmpty() && fileName.contains("xhl.docx")) {
                try (InputStream is = Files.newInputStream(Paths.get(docxPath));
                     XWPFDocument xwpfDocument = new XWPFDocument(is)) {

                    List<XWPFTable> tables = xwpfDocument.getTables();

                    // 处理第二个表格（索引1）
                    if (tables.size() > 1) {
                        XWPFTable table = tables.get(1);

                        // 安全合并第二行到第五行（索引2-5）
                        tryMergeCells(table, 2, 0, STMerge.RESTART);
                        tryMergeCells(table, 3, 0, STMerge.CONTINUE);
                        tryMergeCells(table, 4, 0, STMerge.RESTART);
                        tryMergeCells(table, 5, 0, STMerge.CONTINUE);
                    }

                    // 处理第一个表格（索引0）
                    if (!tables.isEmpty()) {
                        XWPFTable table1 = tables.get(0);

                        // 安全合并第一行到第四行（索引1-4）
                        tryMergeCells(table1, 1, 0, STMerge.RESTART);
                        tryMergeCells(table1, 2, 0, STMerge.CONTINUE);
                        tryMergeCells(table1, 3, 0, STMerge.RESTART);
                        tryMergeCells(table1, 4, 0, STMerge.CONTINUE);
                    }

                    // 保存文档
                    try (FileOutputStream out = new FileOutputStream(docxPath)) {
                        xwpfDocument.write(out);
                    }
                } catch (Exception e) {
                    // 这里可以根据需要记录日志或处理异常
                    throw new RuntimeException("处理文档失败: " + e.getMessage(), e);
                }
            }


            documents4jWordToPdf(docxPath, pdfPath);
            return 200;
        }

    }

    @PostMapping("/jb")
    public int jb(@RequestBody String formData, HttpServletResponse response) throws
            Throwable {

        // 本地开发测试环境
        String basePath = "D:/YH-2025/01-温州三澳/sa-go-gitee-sanao-wcy/public/";
        // 服务器生产环境
//        String basePath = "G:\\qdyh\\zdbz\\wzGo\\public\\";


        JSONObject form = JSONObject.parseObject(formData);
        class T10 {
            //k1-k3
            String k1;
            String k2;
            String k3;
            String k4;
            String k5;
            String k6;
            String k7;
            String k8;
            String k9;
            String k10;
        }
        List<T10> jbList1 = new ArrayList<>();
        List<T10> jbList2 = new ArrayList<>();
//        定义一个string变量
        String fileName = "";
        String imgType = "";
        String region = "";
        String wordName = "";

//        String[] colorArr = {};
        String[][] colorArr = {};
        int[][] twcMerge = {};
        for (Map.Entry<String, Object> entry : form.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (key.equals("fileName")) {
                fileName = (String) value;
            }
            if (key.equals("imgType")) {
                imgType = (String) value;
            }
            if (key.equals("region")) {
                region = (String) value;
            }
            if (key.equals("wordName")) {
                wordName = (String) value;
            }
//            colorArr
            if (key.equals("colorArr")) {
                JSONArray colorArrJson = (JSONArray) value;
                colorArr = new String[colorArrJson.size()][];
                for (int i = 0; i < colorArrJson.size(); i++) {
                    colorArr[i] = colorArrJson.getJSONArray(i).toJavaObject(String[].class);
                }
            }
//            twcMerge
            if (key.equals("twcMerge")) {
                JSONArray twcMergeJson = (JSONArray) value;
                twcMerge = twcMergeJson.toJavaObject(int[][].class);
            }
            if (key.equals("t1")) {
                JSONArray jsonArray = (JSONArray) value;
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    T10 t10 = new T10();
                    t10.k1 = jsonObject.getString("code");
                    t10.k2 = jsonObject.getString("station");
                    t10.k3 = jsonObject.getString("date");
                    t10.k4 = jsonObject.getString("time");
                    t10.k5 = jsonObject.getString("tide");
                    t10.k6 = jsonObject.getString("lan");
                    t10.k7 = jsonObject.getString("huang");
                    t10.k8 = jsonObject.getString("cheng");
                    t10.k9 = jsonObject.getString("hong");
                    t10.k10 = jsonObject.getString("level");
                    jbList1.add(t10);

                }
            }
            if (key.equals("t2")) {
                JSONArray jsonArray = (JSONArray) value;
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    T10 t10 = new T10();
                    t10.k1 = jsonObject.getString("code");
                    t10.k2 = jsonObject.getString("station");
                    t10.k3 = jsonObject.getString("date");
                    t10.k4 = jsonObject.getString("time");
                    t10.k5 = jsonObject.getString("tide");
                    t10.k6 = jsonObject.getString("lan");
                    t10.k7 = jsonObject.getString("huang");
                    t10.k8 = jsonObject.getString("cheng");
                    t10.k9 = jsonObject.getString("hong");
                    t10.k10 = jsonObject.getString("level");
                    jbList2.add(t10);
                }
            }


        }
        LoopRowTableRenderPolicy loopRowTableRenderPolicy = new LoopRowTableRenderPolicy();
        Configure config = Configure.newBuilder()
                .bind("t1", loopRowTableRenderPolicy)
                .bind("t2", loopRowTableRenderPolicy)
                .build();
        String finalImgType = imgType;

        String oldName = basePath + "警报单模板\\" + region + ".docx";
        if (imgType.contains("wave") && region.contains("wz")) {
            oldName = basePath + "警报单模板\\wz_wave.docx";
            if (imgType.contains("info") || imgType.contains("jiechu")) {
                oldName = basePath + "警报单模板\\wz_wave_info.docx";
            }
        }
        if (wordName.contains("twc")) {
            oldName = basePath + "警报单模板\\" + wordName;
            System.out.println(oldName);
        }
        String docxPath = basePath + "jb\\" + fileName;
        String pdfPath = basePath + "jb\\" + fileName.split("\\.")[0] + ".pdf";
        XWPFTemplate.compile(oldName, config).render(new HashMap<String, Object>() {{
            String[] strArr = new String[]{"content1", "content2", "content3", "subTime", "title", "bh", "subject", "time1", "time2", "target"};
            String[] boolArr = new String[]{"isT1", "isImg1", "isFutu"};
            String[] tableArr = new String[]{"tide"};
            String[] imgArr = new String[]{"img2"};

            for (int i = 0; i < imgArr.length; i++) {
                if (!Objects.equals(form.getString(imgArr[i]), "")) {
                    put(imgArr[i], Pictures.of(basePath + "\\png\\" + form.getString(imgArr[i])).fitSize().center().create());
                }
            }

            for (int i = 0; i < strArr.length; i++) {
                if (form.getString(strArr[i]) != null) {
                    put(strArr[i], form.getString(strArr[i]));
                }
            }
            for (int i = 0; i < boolArr.length; i++) {
                if (form.getBoolean(boolArr[i]) != null) {
                    put(boolArr[i], form.getBoolean(boolArr[i]));
                }
            }
            JSONArray tableData = form.getJSONArray("tide");
            put("tide", new ArrayList<HashMap<String, Object>>() {{
//                TableRenderData tableRenderData = null;
                for (int j = 0; j < tableData.size(); j++) {
//                    put("t1",tableRenderData);
                    int finalJ = j;
                    add(new HashMap<String, Object>() {{
                        put("content2", tableData.getJSONObject(finalJ).getString("content2"));
                        put("content3", tableData.getJSONObject(finalJ).getString("content3"));
                        put("t1", new ArrayList<HashMap<String, Object>>() {{
                            JSONArray rowData = tableData.getJSONObject(finalJ).getJSONArray("t1");
                            for (int k = 0; k < rowData.size(); k++) {
                                int finalK = k;
                                add(new HashMap<String, Object>() {{
                                    put("k1", rowData.getJSONObject(finalK).getString("k1"));
                                    put("k2", rowData.getJSONObject(finalK).getString("k2"));
                                    put("k3", rowData.getJSONObject(finalK).getString("k3"));
                                    put("k4", rowData.getJSONObject(finalK).getString("k4"));
                                    put("k5", rowData.getJSONObject(finalK).getString("k5"));
                                    put("k6", rowData.getJSONObject(finalK).getString("k6"));
                                    put("k7", rowData.getJSONObject(finalK).getString("k7"));
                                    put("k8", rowData.getJSONObject(finalK).getString("k8"));
                                    put("k9", rowData.getJSONObject(finalK).getString("k9"));
                                    put("k10", rowData.getJSONObject(finalK).getString("k10"));
                                }});
                            }
                        }});
                    }});
                }
            }});
            put("t1", jbList1);
            put("t2", jbList2);
            put("img1", Pictures.ofLocal(basePath + "灾害图标\\" + form.getString("imgType") + ".png").create());
        }}).writeToFile(docxPath);


        if (colorArr.length > 0) {
            XWPFDocument xwpfDocument = new XWPFDocument(Files.newInputStream(Paths.get(docxPath)));
            List<XWPFTable> tables = xwpfDocument.getTables();
            int num = -1;
            for (int j = 0; j < tables.size(); j++) {
                if (tables.get(j).getText().contains("预警岸段") && !wordName.contains("twc")) {
                    num++;

                    if (Objects.equals(region, "wz") || Objects.equals(region, "hz")) {
                        XWPFTable table = tables.get(j);
                        int rowCount = table.getNumberOfRows();

                        // 设置单元格颜色 - 添加边界检查
                        for (int i = 0; i < colorArr[num].length; i++) {
                            int targetRow = i + 1;
                            if (targetRow < rowCount) { // 确保行存在
                                XWPFTableRow row = table.getRow(targetRow);
                                if (row.getTableCells().size() > 9) { // 确保列存在
                                    row.getCell(9).setColor(colorArr[num][i]);
                                }
                            }
                        }

                        // 合并单元格 - 添加边界检查和安全的POI操作
                        int[][] tableArr = new int[][]{{3, 1, 5, 1}, {3, 2, 5, 2}, {3, 3, 5, 3}, {3, 4, 5, 4},
                                {1, 1, 2, 1}, {1, 2, 2, 2}, {1, 3, 2, 3}, {1, 4, 2, 4},
                                {9, 1, 10, 1}, {9, 2, 10, 2}, {9, 3, 10, 3}, {9, 4, 10, 4}};

                        for (int[] range : tableArr) {
                            int startRow = range[0];
                            int endRow = range[2];
                            int col = range[1];

                            // 检查行范围有效性
                            if (endRow < rowCount) {
                                // 设置起始单元格
                                XWPFTableRow rowStart = table.getRow(startRow);
                                if (rowStart != null && col < rowStart.getTableCells().size()) {
                                    CTTcPr prStart = rowStart.getCell(col).getCTTc().isSetTcPr() ?
                                            rowStart.getCell(col).getCTTc().getTcPr() :
                                            rowStart.getCell(col).getCTTc().addNewTcPr();
                                    CTVMerge vMerge = prStart.isSetVMerge() ?
                                            prStart.getVMerge() :
                                            prStart.addNewVMerge();
                                    vMerge.setVal(STMerge.RESTART);
                                }

                                // 设置后续单元格
                                for (int k = startRow + 1; k <= endRow; k++) {
                                    XWPFTableRow row = table.getRow(k);
                                    if (row != null && col < row.getTableCells().size()) {
                                        CTTcPr pr = row.getCell(col).getCTTc().isSetTcPr() ?
                                                row.getCell(col).getCTTc().getTcPr() :
                                                row.getCell(col).getCTTc().addNewTcPr();
                                        CTVMerge vMergeCont = pr.isSetVMerge() ?
                                                pr.getVMerge() :
                                                pr.addNewVMerge();
                                        vMergeCont.setVal(STMerge.CONTINUE);
                                    }
                                }
                            }
                        }

                    } else {
                        XWPFTable table = tables.get(j);
                        for (int i = 0; i < colorArr[num].length; i++) {
                            table.getRow(i + 1).getCell(9).setColor(colorArr[num][i]);
                        }
                        for (int i = 1; i < table.getRows().size(); i++) {
                            table.getRow(i).getCell(0).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                            table.getRow(i).getCell(1).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                            table.getRow(i).getCell(5).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                            table.getRow(i).getCell(6).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                            table.getRow(i).getCell(7).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                            table.getRow(i).getCell(8).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                        }
                    }


                } else if (tables.get(j).getText().contains("预警岸段") && wordName.contains("twc")) {
                    XWPFTable table = tables.get(j);
                    for (int i = 0; i < colorArr[0].length; i++) {
                        table.getRow(i + 1).getCell(9).setColor(colorArr[0][i]);
                    }
//                        合并项：[[1,1,2,1]]//表示1行1列到2行1列的单元格合并
                    int[][] tableArr = twcMerge;
                    for (int i = 0; i < tableArr.length; i++) {
                        table.getRow(tableArr[i][0]).getCell(tableArr[i][1]).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
//                            table.getRow(tableArr[i][2]).getCell(tableArr[i][3]).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                        for (int k = tableArr[i][0] + 1; k <= tableArr[i][2]; k++) {
                            table.getRow(k).getCell(tableArr[i][1]).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                        }
                    }
                }
            }
            FileOutputStream out = new FileOutputStream(docxPath);
            xwpfDocument.write(out);
            out.close();
        }

        documents4jWordToPdf(docxPath, pdfPath);
        return 200;


    }


    /**
     * 通过docx4j 实现word转pdf
     *
     * @param sourcePath 源文件地址 如 /root/example.doc
     * @param targetPath 目标文件地址 如 /root/example.pdf
     */
    public static void docx4jWordToPdf(String sourcePath, String targetPath) {
        try {
            WordprocessingMLPackage pkg = Docx4J.load(new File(sourcePath));
            Mapper fontMapper = new IdentityPlusMapper();
            fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
            fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
            fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
            fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
            fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
            fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
            fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
            fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
            fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
            fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
            fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
            fontMapper.put("等线", PhysicalFonts.get("SimSun"));
            fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
            fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
            fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
            fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
            fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
            fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
            fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
            fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
            fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
            fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
            fontMapper.put("新細明體", PhysicalFonts.get("SimSun"));
            pkg.setFontMapper(fontMapper);

            Docx4J.toPDF(pkg, new FileOutputStream(targetPath));
        } catch (Exception e) {
            System.out.println("转换失败");
        }
    }

    public static void documents4jWordToPdf(String sourcePath, String targetPath) {


        //        方案2

        //将word转化为pdf文件
        File inputDoc = new File(sourcePath);
        File outputPdf = new File(targetPath);
        try (InputStream docInputStream = new FileInputStream(inputDoc);
             OutputStream pdfOutputStream = new FileOutputStream(outputPdf)) {

            Document document = new Document(docInputStream);
            document.save(pdfOutputStream, SaveFormat.PDF);


        } catch (Exception e) {
            //            log.error("doc文件转pdf文件失败", e);
//            e.printStackTrace();
            System.out.println(e);
        }
    }


    //=== 辅助方法 ===//
// 验证表格行数
    private void validateTableRows(XWPFTable table, int requiredRows, String tableName) {
        if (table.getRows().size() < requiredRows) {
            throw new IllegalStateException(tableName + "需要至少" + requiredRows + "行，实际只有: " + table.getRows().size());
        }
    }

    // 安全设置垂直合并
    private void setVMerge(XWPFTable table, int rowIdx, int colIdx, STMerge.Enum mergeType) {
        XWPFTableRow row = table.getRow(rowIdx);
        if (row == null) {
            throw new IllegalStateException("行索引不存在: " + rowIdx);
        }

        XWPFTableCell cell = row.getCell(colIdx);
        if (cell == null) {
            cell = row.createCell(); // 可选：创建单元格（根据业务需求）
        }

        CTTcPr tcPr = cell.getCTTc().getTcPr();
        if (tcPr == null) {
            tcPr = cell.getCTTc().addNewTcPr();
        }
        tcPr.addNewVMerge().setVal(mergeType);
    }


    // 安全合并单元格方法（跳过不存在的行/单元格）
    private void tryMergeCells(XWPFTable table, int rowIdx, int colIdx, STMerge.Enum mergeType) {
        try {
            // 检查行是否存在
            if (table.getRows().size() <= rowIdx) {
                // 行不存在，跳过合并
                return;
            }

            XWPFTableRow row = table.getRow(rowIdx);
            if (row == null) {
                // 行为空，跳过合并
                return;
            }

            // 检查单元格是否存在
            if (row.getTableCells().size() <= colIdx) {
                // 单元格不存在，跳过合并
                return;
            }

            XWPFTableCell cell = row.getCell(colIdx);
            if (cell == null) {
                // 单元格为空，跳过合并
                return;
            }

            // 执行合并操作
            CTTcPr tcPr = cell.getCTTc().isSetTcPr() ?
                    cell.getCTTc().getTcPr() :
                    cell.getCTTc().addNewTcPr();

            if (tcPr.isSetVMerge()) {
                tcPr.unsetVMerge();
            }
            tcPr.addNewVMerge().setVal(mergeType);

        } catch (Exception e) {
            // 捕获并忽略合并过程中的异常，确保继续执行
            System.err.println("跳过合并操作: (" + rowIdx + "," + colIdx + ") - " + e.getMessage());
        }
    }

    public static RowRenderData getRowRenderData(String[] listRow) {
        RowRenderData row = null;
        TextRenderData[] textRenderDataList = new TextRenderData[listRow.length];
        for (int i = 0; i < listRow.length; i++) {
            textRenderDataList[i] = Texts.of(listRow[i]).fontSize(10.5).fontFamily("宋体").create();
        }
        row = Rows.of(textRenderDataList).center().create();
        return row;
    }
}
